package com.dylan.channel.v6;

import com.dylan.channel.v6.channel.Channel;
import com.dylan.channel.v6.factory.ChannelFactory;
import com.dylan.channel.v6.future.ChannelFuture;
import com.dylan.channel.v6.future.ChannelPromise;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.util.Map;

public class ServerBootstrap {


    volatile EventLoopGroup group;

    volatile EventLoopGroup childGroup;

    private volatile ChannelFactory<? extends Channel> channelFactory;


    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        this.group = parentGroup;
        this.childGroup = childGroup;
        return this;
    }

    public ChannelFuture bind(int port) throws IOException {
        return this.bind(new InetSocketAddress(port));
    }

    private ChannelFuture bind(InetSocketAddress address) throws IOException {
        return this.doBind(address);
    }

    private ChannelFuture doBind(InetSocketAddress address) throws IOException {
        ChannelFuture regFuture = initAndRegister();
        Channel channel = regFuture.channel();

        //TODO构建Promise
        ChannelPromise promise = null;

        this.doBind0(regFuture, channel, address, promise);

        return promise;
    }

    private static void doBind0(final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) {
        channel.eventLoop().execute(new Runnable() {
            public void run() {
//                if (regFuture.isSuccess()) {
//                    channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
//                } else {
//                    promise.setFailure(regFuture.cause());
//                }

            }
        });
    }

    final ChannelFuture initAndRegister() {
        Channel channel = channelFactory.newChannel();

        init(channel);

        //注册ServerSocketChannel
        ChannelFuture channelFuture = group.register(channel);

        return channelFuture;
    }

    void init(Channel channel) {
    }

}
